package tester;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import Comparator.BlockVolumeComparator;

import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import packing.Block;
import packing.BoxPack;
import packing.EmptySpace;
import packing.EmptySpaceBlockPair;
import packing.PositionSimpleBlockPair;
import packing.Reader;
import packing.SimpleBlock;
import packing.State;
import packing.treeSearch.CLTRS;
import packing.treeSearch.Node;
import packing.treeSearch.Packer;
import packing.treeSearch.Tree;


public class tester {
	public static ObjectArrayList<State> readAllTest(){
		ObjectArrayList<State> originalState = new ObjectArrayList<State>();
		originalState.addAll(Reader.readBRSet("TestFiles\\br01.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br02.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br03.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br04.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br05.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br06.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br07.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br08.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br09.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br10.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br11.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br12.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br13.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br14.txt"));
		originalState.addAll(Reader.readBRSet("TestFiles\\br15.txt"));
		return originalState;
	}
	
	public static void main(String [] argv){
		List<State> list= Reader.readBRSet("TestFiles\\hanuman.txt");
		long start_time = System.nanoTime();
		State state = list.get(0);
		EmptySpace emptySpace = state.getEmptySpaceStack().peek(0);
		Packer packer = new Packer();
		
		int count = 1 ;
		do{
			List<Block> blockList = packer.getFitableBlock(state, emptySpace, false, 0.98);
			Collections.sort(blockList, new BlockVolumeComparator());
			CLTRS search = new CLTRS();
			Node<State> root = new Node<State>(state);
			search.extendSolution(root,5,11, blockList);
			
			Tree<State> tree = new Tree<State>(root);
			List<Node<State>> treelist = tree.toList();
			
			
			for(Node<State> s : treelist){
				s.getData().sortByPressure(true);
			}
			List<Node<State>> nodelist = new ArrayList<Node<State>>();
			for (int i = 0; i < treelist.size(); i++) {
				if(treelist.get(i).getData().isFloat() && treelist.get(i).getData().isOutline() && treelist.get(i).getData().checkFloor()){
//				if(treelist.get(i).getData().isFloat() && treelist.get(i).getData().isOutline()){
					nodelist.add(treelist.get(i));
				}
			}
			
			
			double max = 0.0 ;
			String txt = "";
			State bestState = null;
			System.out.println("\n================================== เกิด State ขึ้นทั้งหมด  "+nodelist.size()+"  State ====================================");
			for(int i =0; i<nodelist.size();i++){
				System.out.println("\n==================================State : "+i+"====================================");
				State currentState  = nodelist.get(i).getData();
				System.out.println(currentState.evaluate());
//				if((currentState.getEvaluationScore() > max) && (currentState.getTotalWeight() <= currentState.getContainer().getWeightLimit())){
				if(currentState.getEvaluationScore() > max){
					bestState = currentState;
					max = bestState.getEvaluationScore() ;
					txt = "Best State : "+i+" ( boxplaces_"+i+".txt )" ;
				}		
			}
			System.out.println("======================================================================");
			if(bestState != null){
				bestState.print2File("boxplaces"+count+".txt");
				count++;
				long end_time = System.nanoTime();
				long minute = (long) ((end_time - start_time) / 1000000000.0) / 60;
				long second = (long) ((end_time - start_time) / 1000000000.0) % 60;
				System.out.println(txt + " :: อัตราส่วนการใช้พื้นที่ : "+max+" , น้ำหนักรวม : "+bestState.getTotalWeight()+", ใช้เวลาประมวลผลทั้งสิ้น : "+minute+"."+second+" นาที");
				
//				state = state.getStateResult(bestState);
				List<PositionSimpleBlockPair> positionBlockList = new ObjectArrayList<PositionSimpleBlockPair>();
				for (EmptySpaceBlockPair emptySpaceBlockPair : bestState.getPackedBlockList()) {
					positionBlockList.add(emptySpaceBlockPair.getPairMainBlock());
					if (!emptySpaceBlockPair.getBlock().isSimpleBlock())
						positionBlockList.add(emptySpaceBlockPair.getPairNextBlock());

				}
				for (PositionSimpleBlockPair positionBlockPair : positionBlockList) {
					SimpleBlock simpleBlock = positionBlockPair.getSimpleblock();
					BoxPack b = simpleBlock.getBox();
					for(int i = 0 ; i < state.getBoxInputList().size() ; i++){
						if(b.getId() == state.getBoxInputList().get(i).getId()){
							int quantity = state.getBoxInputList().get(i).getQuantity() - simpleBlock.getBoxNumber() ;
							if(quantity > 0){
								state.getBoxInputList().get(i).setQuantity(quantity);
							}else{
								state.getBoxInputList().remove(i);
							}
						}	
					}			
				}
				for(int i = 0 ; i < state.getBoxInputList().size() ; i++){
					state.getBoxInputList().get(i).setId(i+1);
				}
				state = new State(""+count, state.getContainer(), state.getBoxInputList());
//				for(int i =0; i<nodelist.size();i++){
//					State currentState = nodelist.get(i).getData();
//					if(currentState.getEvaluationScore() >= bestState.getEvaluationScore()){
//						currentState.print2File("boxplaces_"+i+".txt");
//					}
//				}
			}			
		}while(state.getBoxInputList().size() > 0);
	}

}
